/*
* @brief Contains board specific configuration for ODrive v3.x
*/

#ifndef __BOARD_CONFIG_H
#define __BOARD_CONFIG_H

#include <gpio.h>
#include <spi.h>
#include <tim.h>
#include <main.h>

#define SHUNT_RESISTANCE (5e-3f)

typedef struct {
    osPriority thread_priority;
} AxisHardwareConfig_t;

typedef struct {
    uint32_t timer;
    uint32_t index_port;
    uint16_t index_pin;
    uint32_t hallA_port;
    uint16_t hallA_pin;
    uint32_t hallB_port;
    uint16_t hallB_pin;
    uint32_t hallC_port;
    uint16_t hallC_pin;
    uint32_t spi;
} EncoderHardwareConfig_t;
typedef struct {
    uint32_t timer;
    uint16_t control_deadline;
    float shunt_conductance;
} MotorHardwareConfig_t;
typedef struct {
    size_t adc_ch;
} ThermistorHardwareConfig_t;
typedef struct {
    uint32_t spi;
    uint32_t enable_port;
    uint16_t enable_pin;
    uint32_t nCS_port;
    uint16_t nCS_pin;
    uint32_t nFAULT_port;
    uint16_t nFAULT_pin;
} GateDriverHardwareConfig_t;
typedef struct {
    AxisHardwareConfig_t axis_config;
    EncoderHardwareConfig_t encoder_config;
    MotorHardwareConfig_t motor_config;
    ThermistorHardwareConfig_t thermistor_config;
    GateDriverHardwareConfig_t gate_driver_config;
} BoardHardwareConfig_t;

extern const BoardHardwareConfig_t hw_configs[2];

//TODO stick this in a C file
#ifdef __MAIN_CPP__

const BoardHardwareConfig_t hw_configs[2] = { {
    //M0
    .axis_config = {
        .thread_priority = (osPriority)(osPriorityHigh + (osPriority)1),
    },
    .encoder_config = {
        .timer = TIMER2,
        .index_port = M0_ENC_Z_GPIO_Port,
        .index_pin = M0_ENC_Z_Pin,
        
        .hallA_port = M0_ENC_A_GPIO_Port,
        .hallA_pin = M0_ENC_A_Pin,
        .hallB_port = M0_ENC_B_GPIO_Port,
        .hallB_pin = M0_ENC_B_Pin,
        
        .hallC_port = M0_ENC_Z_GPIO_Port,
        .hallC_pin = M0_ENC_Z_Pin,
        .spi = SPI2,
    },
    .motor_config = {
        .timer = TIMER0,
        .control_deadline = TIM_0_7_PERIOD_CLOCKS,
        .shunt_conductance = 1.0f / SHUNT_RESISTANCE,  //[S]
    },
    .thermistor_config = {
        .adc_ch = 5,
    },
    .gate_driver_config = {
        .spi = SPI2,
        // Note: this board has the EN_Gate pin shared!
        .enable_port = EN_GATE_GPIO_Port,
        .enable_pin = EN_GATE_Pin,
        .nCS_port = M0_nCS_GPIO_Port,
        .nCS_pin = M0_nCS_Pin,
        .nFAULT_port = nFAULT_GPIO_Port, // the nFAULT pin is shared between both motors
        .nFAULT_pin = nFAULT_Pin,
    }
},{
    //M1
    .axis_config = {
        .thread_priority = osPriorityHigh,
    },
    .encoder_config = {
        .timer = TIMER3,
        .index_port = M1_ENC_Z_GPIO_Port,
        .index_pin = M1_ENC_Z_Pin,
        .hallA_port = M1_ENC_A_GPIO_Port,
        .hallA_pin = M1_ENC_A_Pin,
        .hallB_port = M1_ENC_B_GPIO_Port,
        .hallB_pin = M1_ENC_B_Pin,
        .hallC_port = M1_ENC_Z_GPIO_Port,
        .hallC_pin = M1_ENC_Z_Pin,
        .spi = SPI2,
    },
    .motor_config = {
        .timer = TIMER7,
        .control_deadline = (3 * TIM_0_7_PERIOD_CLOCKS) / 2,
        .shunt_conductance = 1.0f / SHUNT_RESISTANCE,  //[S]
    },
    .thermistor_config = {
        .adc_ch = 5
    },
    .gate_driver_config = {
        .spi = SPI2,
        // Note: this board has the EN_Gate pin shared!
        .enable_port = EN_GATE_GPIO_Port,
        .enable_pin = EN_GATE_Pin,
        .nCS_port = M1_nCS_GPIO_Port,
        .nCS_pin = M1_nCS_Pin,
        .nFAULT_port = nFAULT_GPIO_Port, // the nFAULT pin is shared between both motors
        .nFAULT_pin = nFAULT_Pin,
    }
} };
#endif

#endif // __BOARD_CONFIG_H
